﻿using CalligraphyWeb;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Calligraphy.Models
{
    public class Rating
    {
        #region Data Members
        private rating data;
        public rating Data
        {
            get
            {
                if (data == null)
                    data = new rating();

                return data;
            }
            set
            {
                if (data == value) return;
                data = value;
            }
        }
        #endregion

        #region Class Methods
        public Rating()
        {
        }

        public Rating(int id, bool isLazy = true)
        {
            Get(id, isLazy);
        }

        public Rating(rating obj)
        {
            Get(obj);
        }
        public Rating Get(int id, bool isLazy = true)
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.Configuration.LazyLoadingEnabled = isLazy;
                var query = from c in db.ratings
                            where c.id == id
                            select c;

                if (query.Count() > 0)
                {
                    var obj = query.FirstOrDefault();
                    return Get(obj);
                }
                else
                    return null;
            }
        }

        public Rating Get(rating obj)
        {
            if (this.data == obj) return this;

            this.data = obj;
            return this;
        }

        private long Insert()
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.ratings.Add(data);
                db.SaveChanges();
                return data.id;
            }
        }

        private long Update()
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.ratings.Attach(data);
                db.Entry(data).State = System.Data.EntityState.Modified;
                db.SaveChanges();
                return data.id;
            }
        }

        public long Save()
        {
            if (data.id == 0)
                return Insert();
            else
                return Update();
        }

        public long Delete()
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.ratings.Remove(data);
                db.SaveChanges();
                return data.id;
            }
        }
        #endregion

        #region Static Methods
        public static ObservableCollection<rating> Get(string sortColumn = "id", bool isAsc = false,
                                                    int pageIndex = 1, int pageSize = 10,
                                                    bool isLazy = true)
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.Configuration.LazyLoadingEnabled = isLazy;
                IQueryable<rating> query = db.ratings.AsQueryable();


                query = Sorting(query, sortColumn, isAsc);
                query = Paging(query, pageIndex, pageSize);

                if (query == null)
                    return new ObservableCollection<rating>();
                else
                    return new ObservableCollection<rating>(query.ToList());
            }
        }

        public static List<long> Save(Collection<rating> collection)
        {
            var result = new List<long>();
            foreach (var obj in collection)
            {
                var temp = new Rating(obj);
                result.Add(temp.Save());
            }

            return result;
        }

        public static int Delete(Collection<rating> collection)
        {
            int result = 0;
            using (calligraphyEntities db = new calligraphyEntities())
            {
                foreach (var obj in collection)
                {
                    db.ratings.Remove(obj);
                    result++;
                }

                db.SaveChanges();
            }
            return result;
        }

        private static IQueryable<rating> Sorting(IQueryable<rating> query, string sortColumn = "id", bool isAsc = false)
        {
            switch (sortColumn)
            {
                case "parent":
                    query = isAsc ? query.OrderBy(o => o.parentid) : query.OrderByDescending(o => o.parentid);
                    break;
                case "createdby":
                    query = isAsc ? query.OrderBy(o => o.createdby) : query.OrderByDescending(o => o.createdby);
                    break;
                case "score":
                    query = isAsc ? query.OrderBy(o => o.score) : query.OrderByDescending(o => o.score);
                    break;
                case "date":
                    query = isAsc ? query.OrderBy(o => o.created) : query.OrderByDescending(o => o.created);
                    break;
                case "id":
                default:
                    query = isAsc ? query.OrderBy(o => o.id) : query.OrderByDescending(o => o.id);
                    break;
            }

            return query;
        }

        private static IQueryable<rating> Paging(IQueryable<rating> query, int pageIndex = 1, int pageSize = 10)
        {
            if (pageIndex <= 1)
                pageIndex = 0;
            else
                pageIndex--;

            return query.Skip(pageIndex * pageSize).Take(pageSize);
        }

        public static ObservableCollection<rating> Search(long parent = 0,
                                        int? scoreFrom = null, int? scoreTo = null,
                                        long createdBy = 0,
                                        DateTime? createFrom = null, DateTime? createTo = null,
                                        string sortColumn = "id", bool isAsc = false,
                                        int pageIndex = 1, int pageSize = 10,
                                        bool isLazy = true)
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.Configuration.LazyLoadingEnabled = isLazy;
                var query = from c in db.ratings
                            where (parent == 0 ? true : c.parentid == parent)
                            && (createdBy == 0 ? true : createdBy == c.createdby)
                            && (scoreFrom == null ? true : scoreFrom.Value <= c.score)
                            && (scoreTo == null ? true : scoreTo.Value >= c.score)
                            && (createFrom == null ? true : createFrom.Value <= c.created)
                            && (createTo == null ? true : createTo.Value >= c.created)
                            select c;

                query = Sorting(query, sortColumn, isAsc);
                query = Paging(query, pageIndex, pageSize);

                if (query.Count() > 0)
                    return new ObservableCollection<rating>(query.ToList());
                else
                    return new ObservableCollection<rating>();
            }
        }
        #endregion
    }
}
